/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package wisimconsole;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.plaf.basic.BasicSliderUI;

/**
 *
 * @author brother
 */
public class TwoTicksSlider extends JSlider implements MouseListener, MouseMotionListener {
    public static final int wTick=25;
    public static final int hTick=25;
    
    public static final String textTick1 = "t1";
    public static final String textTick2 = "t2";
    public static final String textMessage1 = "end time must after start time";
    public static final String textMessage2 = "end time must after start time";
    public static final String toolTips="Click: Left-1 or Right-2";
    
    
    private Color clTick1Def=Color.PINK;
    private Color clTick2Def=Color.GREEN;
    private Color clTickClick=Color.RED;
    
    private Color clTick1=clTick1Def;
    private Color clTick2=clTick2Def;
    
    int width = 0;
    int value2 = 0;
    boolean tick2Clicked = false;
    Rectangle tick2 = new Rectangle(width, 0, wTick, hTick);
    ArrayList<TwoTickListener> listeners = new ArrayList<>();

    public TwoTicksSlider( int min, int max) {
	super(JSlider.HORIZONTAL, min, max, 0);
	setUI(new MySliderUI(this));
	value2 = max;
	setValue(min);
	for (MouseListener l : this.getMouseListeners()) {
	    this.removeMouseListener(l);
	}
	for (MouseMotionListener l : this.getMouseMotionListeners()) {
	    this.removeMouseMotionListener(l);
	}
	for (MouseWheelListener l : this.getMouseWheelListeners()) {
	    this.removeMouseWheelListener(l);
	}

	this.addMouseListener(this);
	this.addMouseMotionListener(this);
	setToolTipText(toolTips);

    }

    public void addTwoChangeListener(TwoTickListener listener) {
	this.listeners.add(listener);
    }

    @Override
    public void paint(Graphics g) {
	super.paint(g);
	width = ((MySliderUI)this.getUI()).getWidthTrack();
	if (width == 0) {
	    tick2.x = width - tick2.width - 1;
	}
	tick2.x = getXFromValue2();
	Graphics2D g2d = (Graphics2D) g;
	g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
	Rectangle t = tick2;
	g2d.setColor(clTick2);
	int[] xs = {t.x, t.x + t.width / 2, t.x}, ys = {t.y, t.y + t.height / 4, t.y + t.height / 2};
	g2d.fillPolygon(xs, ys, 3);
	g2d.setColor(Color.BLUE);
	String start = textTick2;
	g2d.drawString(start, t.x, t.y + t.height - 2);
    }

    private void setValue2(int value) {
	this.value2 = value;
    }

    public int getValue2() {
	return value2;
    }

    private int getXFromValue2() {
	return (int) ((double) value2 * width / (getMaximum() - getMinimum()))+getMinimum();
    }

    @Override
    public void mouseClicked(MouseEvent e) {
	if(e.getX()<((MySliderUI)getUI()).getTrack().x-1 || e.getX()>((MySliderUI)getUI()).getTrack().width){
	    return;
	}
	ChangeEvent event = new ChangeEvent(this);
	if (MouseEvent.BUTTON3 == e.getButton()) {
	    double value = (double) e.getX() / (double) width * ((double) getMaximum() - (double) getMinimum())+(double)getMinimum();
	    int xthumb = ((MySliderUI) getUI()).getXThumb();
	    int xtick2 = e.getX();
	    if (xthumb + wTick >= xtick2) {
		for (TwoTickListener listener : this.listeners) {
		    listener.TickException(textMessage2);
		}
		return;
	    }
	    tick2.setLocation(e.getX(), tick2.y);
	    setValue2((int) value);
	    for (TwoTickListener listener : this.listeners) {
		listener.Tick2Clicked(event);
	    }

	} else if (MouseEvent.BUTTON1 == e.getButton()) {
	    int x = e.getX();
	    double value = (double) x / (double) width * ((double) getMaximum() - (double) getMinimum());
	    int xthumb = e.getX();
	    int xtick2 = tick2.x;
	    if (xthumb + wTick >= xtick2) {
		for (TwoTickListener listener : this.listeners) {
		    listener.TickException(textMessage1);
		}
		return;
	    }
	    ((MySliderUI) this.getUI()).setThumbLocation(x, ((MySliderUI) this.getUI()).getYThumb());

	    setValue((int) value);
	    for (TwoTickListener listener : this.listeners) {
		listener.Tick1Clicked(event);
	    }
	}
	repaint();

    }
    int right = 3;
    int left = 1;
    int mouseButton = 0;

    @Override
    public void mousePressed(MouseEvent e) {
	if (e.getButton() == MouseEvent.BUTTON1) {
	    clTick1=clTickClick;
	    mouseButton = left;
	} else if (e.getButton() == MouseEvent.BUTTON3) {
	    clTick2=clTickClick;
	    mouseButton = right;
	}
	repaint();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
	mouseButton = 0;
	clTick1=clTick1Def;
	clTick2=clTick2Def;
	repaint();
    }

    @Override
    public void mouseEntered(MouseEvent e) {
	
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    @Override
    public void mouseDragged(MouseEvent e) {
	if(e.getX()<((MySliderUI)getUI()).getTrack().x-1 || e.getX()>((MySliderUI)getUI()).getTrack().width){
	    return;
	}
	ChangeEvent event = new ChangeEvent(this);
	if (mouseButton == left) {
	    int x = e.getX();
	    double value = (double) x / (double) width * ((double) getMaximum() - (double) getMinimum());
	    int xthumb = e.getX();
	    int xtick2 = tick2.x;
	    if (xthumb + wTick >= xtick2) {
		for (TwoTickListener listener : this.listeners) {
		    listener.TickException(textMessage1);
		}
		return;
	    }
	    ((MySliderUI) this.getUI()).setThumbLocation(x, ((MySliderUI) this.getUI()).getYThumb());

	    setValue((int) value);
	    for (TwoTickListener listener : this.listeners) {
		listener.Tick1Clicked(event);
	    }
	} else if (mouseButton == right) {
	    double value = (double) e.getX() / (double) width * ((double) getMaximum() - (double) getMinimum());
	    int xthumb = ((MySliderUI) getUI()).getXThumb();
	    int xtick2 = e.getX();
	    if (xthumb + wTick >= xtick2) {
		for (TwoTickListener listener : this.listeners) {
		    listener.TickException(textMessage2);
		}
		return;
	    }
	    tick2.setLocation(e.getX(), tick2.y);
	    setValue2((int) value);
	    for (TwoTickListener listener : this.listeners) {
		listener.Tick2Clicked(event);
	    }
	}
	repaint();
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }

    interface TwoTickListener {

	void Tick1Clicked(ChangeEvent e);

	void Tick2Clicked(ChangeEvent e);

	void TickException(String message);
    }

    class MySliderUI extends BasicSliderUI {

	private float[] fracs = {0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f};
	private LinearGradientPaint p;
	Color[] colors = {Color.red, Color.yellow, Color.green, Color.cyan, Color.blue, Color.magenta};

	public MySliderUI(JSlider slider) {
	    super(slider);



	}

	@Override
	public void paintTrack(Graphics g) {
	    Graphics2D g2d = (Graphics2D) g;
	    Rectangle t = trackRect;
	    Point2D start = new Point2D.Float(t.x, t.y);
	    Point2D end = new Point2D.Float(t.width, t.height);
	    p = new LinearGradientPaint(start, end, fracs, colors);
	    g2d.setPaint(p);
	    g2d.fillRect(t.x, t.y, t.width, t.height / 4);

	}
	public int getWidthTrack(){
	    return trackRect.width;
	}
	public Rectangle getTrack(){
	    return trackRect;
	}
	static final String start = textTick1;

	@Override
	public void paintThumb(Graphics g) {
	    Graphics2D g2d = (Graphics2D) g;
	    g2d.setRenderingHint(
		    RenderingHints.KEY_ANTIALIASING,
		    RenderingHints.VALUE_ANTIALIAS_ON);

	    Rectangle t = thumbRect;
	    t.width = wTick;
	    t.height = hTick;
	    t.y = 0;
	    g2d.setColor(clTick1);
	    int[] xs = {t.x, t.x + t.width / 2, t.x + t.width / 2},
		    ys = {t.y + t.height / 4, t.y, t.y + t.height / 2};
	    g2d.fillPolygon(xs, ys, 3);
	    g2d.setColor(Color.BLUE);
	    g2d.drawString(start, t.x + 2, t.y + t.height - 2);
	}

	public int getXThumb() {
	    return thumbRect.x;
	}

	public int getYThumb() {
	    return thumbRect.y;
	}

	public void setXThumb(int x) {
	    thumbRect.x = x;
	}
    }
}
